home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / MJKWARP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  8.0 KB  |  330 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994.  */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>       /* for cos(), sin(), and sqrt() */
  12. #include <GL/glut.h>
  13.  
  14. extern unsigned char mjk_image[];
  15. extern int mjk_depth;
  16. extern int mjk_height;
  17. extern int mjk_width;
  18.  
  19. float tick1 = 0;
  20. float tick2 = 0;
  21. float angle;
  22. float size;
  23. int set_timeout = 0;
  24. int visible = 0;
  25. int spinning = 1;
  26. int scaling = 1;
  27. int interval = 100;
  28. #define CUBE 1
  29. #define SQUARES 2
  30. #define DRUM 3
  31. int mode = SQUARES;
  32.  
  33. void
  34. animate(int value)
  35. {
  36.   if (visible) {
  37.     if (spinning || scaling) {
  38.       if (value) {
  39.         if (spinning) {
  40.           tick1 += 4 * (interval / 100.0);
  41.           angle = ((int) tick1) % 360;
  42.         }
  43.         if (scaling) {
  44.           tick2 += 2 * (interval / 100.0);
  45.           size = .7 - .5 * sin(tick2 / 20.0);
  46.         }
  47.       }
  48.       glutPostRedisplay();
  49.       set_timeout = 1;
  50.     }
  51.   }
  52. }
  53.  
  54. #define TIMEDELTA(dest, src1, src2) { \
  55.         if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) {\
  56.               (dest).tv_usec += 1000000;\
  57.               (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1;\
  58.         } else  (dest).tv_sec = (src1).tv_sec - (src2).tv_sec;  }
  59.  
  60. void
  61. redraw(void)
  62. {
  63.   int begin, end, elapsed;
  64.   int i, j;
  65.   float amplitude;
  66.  
  67.   if (set_timeout) {
  68.     begin = glutGet(GLUT_ELAPSED_TIME);
  69.   }
  70.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  71.   glPushMatrix();
  72.  
  73.   if (mode != DRUM) {
  74.     glScalef(size, size, size);
  75.   }
  76.   switch (mode) {
  77.   case SQUARES:
  78.  
  79. #define COLS 6
  80. #define TILE_TEX_W (1.0/COLS)
  81. #define ROWS 6
  82. #define TILE_TEX_H (1.0/ROWS)
  83.  
  84.     glTranslatef(-COLS / 2.0 + .5, -ROWS / 2.0 + .5, 0);
  85.     for (i = 0; i < COLS; i++) {
  86.       for (j = 0; j < ROWS; j++) {
  87.  
  88.         glPushMatrix();
  89.         glTranslatef(i, j, 0);
  90.         glRotatef(angle, 0, 1, 1);
  91.         glBegin(GL_QUADS);
  92.         glTexCoord2f(i * TILE_TEX_W, j * TILE_TEX_H);
  93.         glVertex2f(-.5, -.5);
  94.         glTexCoord2f((i + 1) * TILE_TEX_W, j * TILE_TEX_H);
  95.         glVertex2f(.5, -.5);
  96.         glTexCoord2f((i + 1) * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  97.         glVertex2f(.5, .5);
  98.         glTexCoord2f(i * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  99.         glVertex2f(-.5, .5);
  100.         glEnd();
  101.         glPopMatrix();
  102.  
  103.       }
  104.     }
  105.     break;
  106.   case DRUM:
  107.  
  108. #undef COLS
  109. #undef TILE_TEX_W
  110. #undef ROWS
  111. #undef TILE_TEX_H
  112. #define COLS 12
  113. #define TILE_TEX_W (1.0/COLS)
  114. #define ROWS 12
  115. #define TILE_TEX_H (1.0/ROWS)
  116.  
  117.     glRotatef(angle, 0, 0, 1);
  118.     glTranslatef(-COLS / 2.0 + .5, -ROWS / 2.0 + .5, 0);
  119.     amplitude = 0.4 * sin(tick2 / 6.0);
  120.     for (i = 0; i < COLS; i++) {
  121.       for (j = 0; j < ROWS; j++) {
  122.  
  123. #define Z(x,y)    (((COLS-(x))*(x) + (ROWS-(y))*(y)) * amplitude) - 28.0
  124.  
  125.         glPushMatrix();
  126.         glTranslatef(i, j, 0);
  127.         glBegin(GL_QUADS);
  128.         glTexCoord2f(i * TILE_TEX_W, j * TILE_TEX_H);
  129.         glVertex3f(-.5, -.5, Z(i, j));
  130.         glTexCoord2f((i + 1) * TILE_TEX_W, j * TILE_TEX_H);
  131.         glVertex3f(.5, -.5, Z(i + 1, j));
  132.         glTexCoord2f((i + 1) * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  133.         glVertex3f(.5, .5, Z(i + 1, j + 1));
  134.         glTexCoord2f(i * TILE_TEX_W, (j + 1) * TILE_TEX_H);
  135.         glVertex3f(-.5, .5, Z(i, j + 1));
  136.         glEnd();
  137.         glPopMatrix();
  138.  
  139.       }
  140.     }
  141.     break;
  142.   case CUBE:
  143.     glRotatef(angle, 0, 1, 0);
  144.     glBegin(GL_QUADS);
  145.  
  146.     /* front */
  147.     glTexCoord2f(0.0, 0.0);
  148.     glVertex3f(-1.0, -1.0, 1.0);
  149.     glTexCoord2f(1.0, 0.0);
  150.     glVertex3f(1.0, -1.0, 1.0);
  151.     glTexCoord2f(1.0, 1.0);
  152.     glVertex3f(1.0, 1.0, 1.0);
  153.     glTexCoord2f(0.0, 1.0);
  154.     glVertex3f(-1.0, 1.0, 1.0);
  155.  
  156.     /* back */
  157.     glTexCoord2f(0.0, 1.0);
  158.     glVertex3f(-1.0, 1.0, -1.0);
  159.     glTexCoord2f(1.0, 1.0);
  160.     glVertex3f(1.0, 1.0, -1.0);
  161.     glTexCoord2f(1.0, 0.0);
  162.     glVertex3f(1.0, -1.0, -1.0);
  163.     glTexCoord2f(0.0, 0.0);
  164.     glVertex3f(-1.0, -1.0, -1.0);
  165.  
  166.     /* left */
  167.     glTexCoord2f(0.0, 0.0);
  168.     glVertex3f(-1.0, -1.0, -1.0);
  169.     glTexCoord2f(1.0, 0.0);
  170.     glVertex3f(-1.0, -1.0, 1.0);
  171.     glTexCoord2f(1.0, 1.0);
  172.     glVertex3f(-1.0, 1.0, 1.0);
  173.     glTexCoord2f(0.0, 1.0);
  174.     glVertex3f(-1.0, 1.0, -1.0);
  175.  
  176.     /* right */
  177.     glTexCoord2f(0.0, 1.0);
  178.     glVertex3f(1.0, 1.0, -1.0);
  179.     glTexCoord2f(1.0, 1.0);
  180.     glVertex3f(1.0, 1.0, 1.0);
  181.     glTexCoord2f(1.0, 0.0);
  182.     glVertex3f(1.0, -1.0, 1.0);
  183.     glTexCoord2f(0.0, 0.0);
  184.     glVertex3f(1.0, -1.0, -1.0);
  185.  
  186.     glEnd();
  187.   }
  188.  
  189.   glPopMatrix();
  190.   glutSwapBuffers();
  191.   if (set_timeout) {
  192.     set_timeout = 0;
  193.     end = glutGet(GLUT_ELAPSED_TIME);
  194.     elapsed = end - begin;
  195.     if (elapsed > interval) {
  196.       glutTimerFunc(0, animate, 1);
  197.     } else {
  198.       glutTimerFunc(interval - elapsed, animate, 1);
  199.     }
  200.   }
  201. }
  202.  
  203. int width;
  204. int height;
  205. int depth;
  206. unsigned char *bits;
  207.  
  208. void
  209. visibility(int state)
  210. {
  211.   if (state == GLUT_VISIBLE) {
  212.     visible = 1;
  213.     animate(0);
  214.   } else {
  215.     visible = 0;
  216.   }
  217. }
  218.  
  219. void
  220. minify_select(int value)
  221. {
  222.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, value);
  223.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  224.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  225.   glutPostRedisplay();
  226. }
  227.  
  228. void
  229. rate_select(int value)
  230. {
  231.   interval = value;
  232. }
  233.  
  234. void
  235. menu_select(int value)
  236. {
  237.   switch (value) {
  238.   case 1:
  239.     spinning = !spinning;
  240.     if (spinning)
  241.       animate(0);
  242.     break;
  243.   case 2:
  244.     scaling = !scaling;
  245.     if (scaling)
  246.       animate(0);
  247.     break;
  248.   case 3:
  249.     mode++;
  250.     if (mode > DRUM)
  251.       mode = CUBE;
  252.     switch (mode) {
  253.     case CUBE:
  254.       glEnable(GL_CULL_FACE);
  255.       glDisable(GL_DEPTH_TEST);
  256.       break;
  257.     case SQUARES:
  258.       glDisable(GL_CULL_FACE);
  259.       glDisable(GL_DEPTH_TEST);
  260.       break;
  261.     case DRUM:
  262.       glEnable(GL_DEPTH_TEST);
  263.       glDisable(GL_CULL_FACE);
  264.       break;
  265.     }
  266.     glutPostRedisplay();
  267.     break;
  268.   case 666:
  269.     exit(0);
  270.   }
  271. }
  272.  
  273. int
  274. main(int argc, char **argv)
  275. {
  276.   int minify_menu, rate_menu;
  277.  
  278.   glutInit(&argc, argv);
  279.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  280.   glutCreateWindow("mjkwarp");
  281.   glutDisplayFunc(redraw);
  282.   glMatrixMode(GL_PROJECTION);
  283.   gluPerspective( /* field of view in degree */ 40.0,
  284.   /* aspect ratio */ 1.0,
  285.     /* Z near */ 1.0, /* Z far */ 70.0);
  286.   glMatrixMode(GL_MODELVIEW);
  287.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,30) */
  288.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  289.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  290.   depth = mjk_depth;
  291.   width = mjk_width;
  292.   height = mjk_height;
  293.   bits = mjk_image;
  294.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  295.   gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height,
  296.     GL_RGB, GL_UNSIGNED_BYTE, bits);
  297.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  298.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  299.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  300.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  301.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  302.   glEnable(GL_TEXTURE_2D);
  303.   glutVisibilityFunc(visibility);
  304.   minify_menu = glutCreateMenu(minify_select);
  305.   glutAddMenuEntry("Nearest", GL_NEAREST);
  306.   glutAddMenuEntry("Linear", GL_LINEAR);
  307.   glutAddMenuEntry("Nearest mipmap nearest", GL_NEAREST_MIPMAP_NEAREST);
  308.   glutAddMenuEntry("Linear mipmap nearest", GL_LINEAR_MIPMAP_NEAREST);
  309.   glutAddMenuEntry("Nearest mipmap linear", GL_NEAREST_MIPMAP_LINEAR);
  310.   glutAddMenuEntry("Linear mipmap linear", GL_LINEAR_MIPMAP_LINEAR);
  311.   rate_menu = glutCreateMenu(rate_select);
  312.   glutAddMenuEntry(" 2/sec", 500);
  313.   glutAddMenuEntry(" 6/sec", 166);
  314.   glutAddMenuEntry("10/sec", 100);
  315.   glutAddMenuEntry("20/sec", 50);
  316.   glutAddMenuEntry("30/sec", 33);
  317.   glutAddMenuEntry("60/sec", 16);
  318.   glutCreateMenu(menu_select);
  319.   glutAddMenuEntry("Toggle spinning", 1);
  320.   glutAddMenuEntry("Toggle scaling", 2);
  321.   glutAddMenuEntry("Switch mode", 3);
  322.   glutAddSubMenu("Minimum frame rate", rate_menu);
  323.   glutAddSubMenu("Minify modes", minify_menu);
  324.   glutAddMenuEntry("Quit", 666);
  325.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  326.   menu_select(3);
  327.   glutMainLoop();
  328.   return 0;             /* ANSI C requires main to return int. */
  329. }
  330.